package org.geom.curve;

import java.util.ArrayList;

import org.geom.Point3D;
import org.geom.Vector3D;

public abstract class Curve implements ICurve {

	//---------------------------------------------------------------------- statics
	public static int length = 240;
	
	public float arc = 0.8f;
	
	//---------------------------------------------------------------------- protected
	protected ArrayList<Point3D> points;
	
	protected float t = 0;
	
	//---------------------------------------------------------------------- abstract
	
	/* (non-Javadoc)
	 * @see org.geom.curve.ICurve#sample(float)
	 */
	public abstract Point3D sample(float t);
	protected abstract Vector3D derivateI(float t);
	protected abstract Vector3D derivateII(float t);
	
	//---------------------------------------------------------------------- publics
	
	/* (non-Javadoc)
	 * @see org.geom.curve.ICurve#getPoints()
	 */
	public ArrayList<Point3D> getPoints() {
		float t = 0;
		float dt = this.getArc();

		Point3D p1 = new Point3D();

		points = new ArrayList<Point3D>();
		points.add( sample(0) );
		for(int i=1; i<= Curve.length; i++) {
			p1 = sample(t);
			points.add( p1 );
			t += dt;
		}	
		
		return points;
	}
	
	/* (non-Javadoc)
	 * @see org.geom.curve.ICurve#tangent(float)
	 */
	public Vector3D tangent(float t) {
		Vector3D tangentVector = derivateI(t);
		tangentVector = tangentVector.normalize();
		if (tangentVector==null) {
			System.out.println("Curve > tangent > derivateI is null");
			return new Vector3D(); //TODO
		}
		return tangentVector;
	}
	
	/* (non-Javadoc)
	 * @see org.geom.curve.ICurve#binormal(float)
	 */
	public Vector3D binormal(float t) {
		Vector3D derivataI = derivateI(t);
		Vector3D derivataII = derivateII(t);
		Vector3D binormalVector = Vector3D.crossProduct(derivataI, derivataII).normalize();
		/* Il vettore binormale è definito come prodotto vettoriale fra la derivataI e la derivataII.
		 * Il prodotto vettoriale è definito come il prodotto dei moduli per il seno
		 * dell'angolo insito fra i due vettori.
		 * */		
		return binormalVector;
	}

	/* (non-Javadoc)
	 * @see org.geom.curve.ICurve#normal(float)
	 */
	public Vector3D normal(float t) {
		/*
		 * vettore normale: binormale (prodotto scalare) tangente
		 * */
		return Vector3D.crossProduct(binormal(t), tangent(t));//.normalize();	
	}
	
	
	public void setCurrentPoint(float t) {
		this.t = t;
	}
	public Point3D getCurrentPoint() {
		return sample(t);
	}
	public float getCurrentT() {
		return this.t;
	}
	
	public static void setLenght(float n, boolean increment) {
		if(increment)length+=n;
		else length=(int) n;
	}
}
